//////////////////////////////////////////////////
// Common.cpp
//
// Author: Tarik Belabbas et Adrien Hoffer
//////////////////////////////////////////////////

#include "Common.h"
#include <QMessageBox>

#define TITLE_SIZE		50
#define MESSAGE_SIZE	( ST_ERROR_BUFFER_SIZE + 512 )

char g_errorMessage[ ST_ERROR_BUFFER_SIZE ];

///---------------------------------------------------------
void stErrorInfo::setMessage( const char* _format, ... )
{
	va_list argList;
	va_start( argList, _format );

	setMessage( _format, argList );

	va_end( argList );
}

///---------------------------------------------------------
void stErrorInfo::setMessage( const char* _format, va_list _argList )
{
	ST_VSNPRINTF( m_message, ST_ERROR_BUFFER_SIZE, _format, _argList);
}

//---------------------------------------------------------
const char* formatErrorMessage( const char* _format, ... )
{
	va_list argList;
	va_start( argList, _format );

	ST_VSNPRINTF( g_errorMessage, ST_ERROR_BUFFER_SIZE, _format, argList);

	va_end( argList );

	return g_errorMessage;
}

//---------------------------------------------------------
void errorMsg( stEErrorType _errorT, const char* _file,
		const unsigned int _line, const char* _func, const char* _expr,
		const char* _msg, bool& _cancel )
{
	_cancel = false;

	switch ( _errorT )
	{

		case stEErrorType_LOG:
			{
				stErrorInfo info( stEErrorType_LOG, _file, _line, _func, _expr );
				info.setMessage( _msg );
				//wcoLogManager::s_getInstance()->logMessage( wcoELogType_ENGINE, info);
				qDebug() << info.getMessage();
			}
			break;

		case stEErrorType_WARNING:
			{
				stErrorInfo info( stEErrorType_WARNING, _file, _line, _func, _expr );
				info.setMessage( _msg );
				//if (wcoLogManager::s_getInstance())
				//	wcoLogManager::s_getInstance()->logMessage( wcoELogType_ENGINE, info);
			}
			break;

		case stEErrorType_ASSERT:
			{
				stErrorInfo info( stEErrorType_ASSERT, _file, _line, _func, _expr );
				info.setMessage( _msg );
				_cancel = callAssert( info );
			}
			break;

		case stEErrorType_ERROR:
			{
				stErrorInfo info( stEErrorType_ERROR, _file, _line, _func, _expr );
				info.setMessage( _msg );
				_cancel = callError( info );
			}
			break;

		default:
			break;
	}
}

///---------------------------------------------------------
bool callAssert( const stErrorInfo& _error )
{
	//printToLog( _error);

	unsigned int retcode = messageBox( _error );
	return ( retcode != 0 );
}

///---------------------------------------------------------
bool callError( const stErrorInfo& _error )
{
	//printToLog( _error);

	unsigned int retcode = messageBox( _error );
	return ( retcode != 0 );
}

///---------------------------------------------------------
int messageBox( const stErrorInfo& _error )
{
	char title[ TITLE_SIZE ];
	char message[ MESSAGE_SIZE ];

	switch ( _error.getType() )
	{
		default:
		case stEErrorType_ERROR:
			ST_SNPRINTF( title, TITLE_SIZE, "Application Error" );
			break;

		case stEErrorType_ASSERT:
			ST_SNPRINTF( title, TITLE_SIZE, "Assertion Failed" );
			break;

		case stEErrorType_WARNING:
			ST_SNPRINTF( title, TITLE_SIZE, "Warning" );
			break;
	}

	const char* fileName = _error.getFile();/*getShortFileName( _error.getFile() )*/;

	int length = ST_SNPRINTF( message, MESSAGE_SIZE,
			"%s.\n\nLocation : %s(%d)\nFunction : %s()", title, fileName,
			_error.getLine(), _error.getFunc() );

	if ( _error.getExpr() )
	{
		length += ST_SNPRINTF( message + length, MESSAGE_SIZE - length,
				"\n\nExpression : %s", _error.getExpr() );
	}

	length += ST_SNPRINTF( message + length, MESSAGE_SIZE - length,
			"\n\n%s", _error.getMessage() );

	QMessageBox messageBox;

#ifndef QT_NO_DEBUG // DEBUG
	{
		length += ST_SNPRINTF( message + length, MESSAGE_SIZE - length,
				"\n\nWould you like to debug ? (Cancel to ignore similar messages)" );
		messageBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel );
		messageBox.setDefaultButton( QMessageBox::No );
	}
#else
	{
		length += ST_SNPRINTF( message + length, MESSAGE_SIZE - length,
				"\n\nAbort to exit, Retry to continue, Ignore to skip similar messages." );
		messageBox.setStandardButtons( QMessageBox::Abort | QMessageBox::Retry | QMessageBox::Ignore );
		messageBox.setDefaultButton( QMessageBox::Retry );
	}
#endif

	message[ MESSAGE_SIZE - 1 ] = '\0';

	if ( _error.getType() == stEErrorType_ERROR )
	{
		messageBox.setIcon( QMessageBox::Critical );
	}
	else
	{
		messageBox.setIcon( QMessageBox::Warning );
	}

	messageBox.setText( message );
	messageBox.setWindowTitle( title );
	//messageBox.setInformativeText( "Do you want to save your changes?" );

	int result = messageBox.exec();

#ifndef QT_NO_DEBUG // DEBUG
	if ( result == QMessageBox::Yes )
	{
		asm( "int $3" );
	}
	if ( result == QMessageBox::Cancel )
	{
		return 0;
	}
#else
	if ( result == QMessageBox::Abort )
	{
		ST_EXIT();
	}
	if ( result == QMessageBox::Ignore )
	{
		return 0;
	}
#endif

	return 1;
}

